package com.noble.meether.chat.ui.agora.model;

import com.noble.library.log.PLogger;

import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;

import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;

/**
 * 引擎回调实现类
 * Created by Su on 2017/4/18.
 */
public class IRtcEngineHandler extends IRtcEngineEventHandler {
    private static final String TAG = "IRtcEngineHandler";
    private boolean isLog = false;       // 是否打印Log开关

    private ConcurrentHashMap<AGEventHandler, Integer> mEventHandlerList;

    public IRtcEngineHandler(ConcurrentHashMap<AGEventHandler, Integer> mEventHandlerList) {
        this.mEventHandlerList = mEventHandlerList;
    }

    @Override
    public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onJoinChannelSuccess(channel, uid, elapsed);
            printLog("  onJoinChannelSuccess： channel = " + channel + ", uid = " + uid + ", elapsed = " + elapsed);
        }
    }

    @Override
    public void onRejoinChannelSuccess(String channel, int uid, int elapsed) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onRejoinChannelSuccess(channel, uid, elapsed);
            printLog("  onRejoinChannelSuccess: elapsed = " + elapsed);
        }
    }

    @Override
    public void onFirstRemoteVideoDecoded(int uid, int width, int height, int elapsed) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onFirstRemoteVideoDecoded(uid, width, height, elapsed);
            printLog("  onFirstRemoteVideoDecoded: elapsed = " + elapsed);
        }
    }

    @Override
    public void onFirstLocalVideoFrame(int width, int height, int elapsed) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onFirstLocalVideoFrame(width, height, elapsed);
            printLog("  onFirstLocalVideoFrame: elapsed = " + elapsed);
        }
    }

    @Override
    public void onFirstRemoteVideoFrame(int uid, int width, int height, int elapsed) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onFirstRemoteVideoFrame(uid, width, height, elapsed);
            printLog("  onFirstRemoteVideoFrame: elapsed = " + elapsed);
        }
    }

    @Override
    public void onUserJoined(int uid, int elapsed) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onUserJoined(uid, elapsed);
            printLog("  onUserJoined: elapsed = " + elapsed);
        }
    }

    @Override
    public void onUserOffline(int uid, int reason) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onUserOffline(uid, reason);
            printLog("  onUserOffline: code = " + reason + "\n原因 = " + AGEventHandler.offlineReason(reason));
        }
    }

    @Override
    public void onUserMuteVideo(int uid, boolean muted) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onUserMuteVideo(uid, muted);
            printLog("  onUserMuteVideo: muted = " + muted);
        }
    }

    @Override
    public void onUserEnableVideo(int uid, boolean enabled) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onUserEnableVideo(uid, enabled);
            printLog("  onUserEnableVideo: enabled = " + enabled);
        }
    }

    @Override
    public void onRtcStats(RtcStats stats) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onRtcStats(stats);
            printLog("  onRtcStats: \n通话时长(s) = " + stats.totalDuration +
                    "\n发送字节数(bytes) = " + stats.txBytes +
                    "\n接收字节数(bytes) = " + stats.rxBytes +
                    "\n发送码率(kbps) = " + stats.txKBitRate +
                    "\n接收码率(kbps) = " + stats.rxKBitRate +
                    "\n客户端接入网络质量 = 暂未提供Api" +
                    "\n当前系统的CPU使用率(%) = " + stats.cpuTotalUsage +
                    "\n当前应用程序的CPU使用率(%) = " + stats.cpuAppUsage);
        }
    }

    @Override
    public void onRemoteVideoStats(RemoteVideoStats stats) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onRemoteVideoStats(stats);
            printLog("  onRemoteVideoStats: " + "delay = " + stats.delay +
                    ", 接收码率(kbps) = " + stats.receivedBitrate +
                    ", 接收帧率(fps) = " + stats.receivedFrameRate +
                    ", 视频流类型(大流，小流) = " + stats.rxStreamType);
        }
    }

    @Override
    public void onLocalVideoStats(LocalVideoStats stats) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onLocalVideoStats(stats);
            printLog("  onLocalVideoStats: " + "码率(kbps) = " + stats.sentBitrate + ", 帧率(fps) = " + stats.sentFrameRate);
        }
    }

    @Override
    public void onAudioVolumeIndication(AudioVolumeInfo[] speakerInfos, int totalVolume) {
        if (speakerInfos == null)
            return;

        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onAudioVolumeIndication(speakerInfos, totalVolume);
            printLog("  onAudioVolumeIndication: 说话者音量 = " + speakerInfos[1] +
                    ", （混音后）总音量 = " + totalVolume);
        }
    }

    @Override
    public void onAudioQuality(int uid, int quality, short delay, short lost) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onAudioQuality(uid, quality, delay, lost);
            printLog("  onAudioQuality: 语音质量 = " + quality +
                    ", delay = " + delay + ", 丢包率（百分比） = " + lost);
        }
    }

    @Override
    public void onLeaveChannel(RtcStats stats) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onLeaveChannel(stats);
            printLog("  onLeaveChannel: \n通话时长(s) = " + stats.totalDuration +
                    "\n发送字节数(bytes) = " + stats.txBytes +
                    "\n接收字节数(bytes) = " + stats.rxBytes +
                    "\n发送码率(kbps) = " + stats.txKBitRate +
                    "\n接收码率(kbps) = " + stats.rxKBitRate +
                    "\n客户端接入网络质量 = 暂未提供Api" +
                    "\n当前系统的CPU使用率(%) = " + stats.cpuTotalUsage +
                    "\n当前应用程序的CPU使用率(%) = " + stats.cpuAppUsage);
        }
    }

    @Override
    public void onLastmileQuality(int quality) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onLastmileQuality(quality);
            printLog("  onLastmileQuality: quality = " + quality + "\n网络质量 = " + AGEventHandler.netQuality(quality));
        }
    }

    @Override
    public void onNetworkQuality(int uid, int txQuality, int rxQuality) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onNetworkQuality(uid, txQuality, rxQuality);
            printLog("  onNetworkQuality: " + "\n上行网络质量 = " + txQuality + "  " + AGEventHandler.netQuality(txQuality) +
                    "\n下行网络质量 = " + rxQuality + "  " + AGEventHandler.netQuality(rxQuality));
        }
    }

    @Override
    public void onStreamMessage(int uid, int streamId, byte[] data) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onStreamMessage(uid, streamId, data);
            printLog("  onStreamMessage: " + "data = " + Arrays.toString(data));
        }
    }

    public void onStreamMessageError(int uid, int streamId, int error, int missed, int cached) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onStreamMessageError(uid, streamId, error, missed, cached);
            printLog("  onStreamMessageError: " + "errorCode = " + error +
                    ",  missed = " + missed + ", cached = " + cached);
        }
    }

    @Override
    public void onConnectionLost() {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onConnectionLost();
            printLog("  onConnectionLost");
        }
    }

    @Override
    public void onConnectionInterrupted() {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onConnectionInterrupted();
            printLog("  onConnectionInterrupted");
        }
    }

    @Override
    public void onAudioRouteChanged(int routing) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onAudioRouteChanged(routing);
            printLog("  onAudioRouteChanged = " + routing);
        }
    }

    @Override
    public void onWarning(int warn) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onWarning(warn);
            printLog("  onWarning = " + warn + "\n警告描述： " + AGEventHandler.warnCode(warn));
        }
    }

    @Override
    public void onError(int error) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onExtraCallback(AGEventHandler.EventType.ON_AGORA_MEDIA_ERROR, error, RtcEngine.getErrorDescription(error));
            printLog("  onError = " + error + "\n错误描述：" + AGEventHandler.errorCode(error));
        }
    }

    @Override
    public void onAudioMixingFinished() {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onAudioMixingFinished();
            printLog("  onAudioMixingFinished");
        }
    }

//    @Override
//    public void onRequestChannelKey() {
//        Iterator<AGEventHandler> it = mEventHandlerList.keySet().iterator();
//        while (it.hasNext()) {
//            AGEventHandler handler = it.next();
//            handler.onRequestChannelKey();
//            printLog("  onRequestChannelKey");
//        }
//    }

    @Override
    public void onVideoStopped() {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onVideoStopped();
            printLog("  onVideoStopped");
        }
    }

    @Override
    public void onCameraReady() {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onCameraReady();
            printLog("  onCameraReady");
        }
    }

    @Override
    public void onUserMuteAudio(int uid, boolean muted) {
        for (AGEventHandler handler : mEventHandlerList.keySet()) {
            handler.onUserMuteAudio(uid, muted);
            printLog("  onUserMuteAudio: muted = " + muted);
        }
    }

    /**
     * SDK回调打印控制
     */
    private void printLog(String msg) {
        if (isLog)
            PLogger.d(TAG + msg);
    }
}
